import React from 'react'
import './index.less'

class ImgPreview extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      ratio: 1,
      angle: 0,
      defaultWidth: 'auto',
      defaultHeight: 'auto',
      imgSrc: this.props.detail.url,
      posTop: 0,
      posLeft: 0,
    }
    this.flags = false
    this.isDraged = false
    this.position = {
      x: 0,
      y: 0,
    }
    this.dx = ''
    this.dy = ''
  }

  componentDidMount() {
    this.loadImage()
  }

  // eslint-disable-next-line camelcase
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (nextProps?.detail?.url !== this.props.detail?.url) {
      this.isDraged = false
      this.setState(
        {
          imgSrc: nextProps.detail.url,
          ratio: 1,
          angle: 0,
        },
        () => {
          this.loadImage()
        },
      )
    }
  }

  /**
   * @name: loadImage
   * @desc: 预加载 - 得到图片原始宽高
   */
  loadImage = () => {
    const img = new Image()
    img.src = this.state.imgSrc
    img.onload = () => {
      // 图片原始宽高
      this.originWidth = img.width
      this.originHeight = img.height
      this.getImgSize()
    }
  }

  /**
   * @name: getImgSize
   * @desc: 获取预览图片的默认宽高和位置
   */
  getImgSize = () => {
    const { ratio } = this.state
    let posTop = 0
    let posLeft = 0

    // 默认最大宽高
    let maxDefaultWidth = document.getElementsByClassName('file-content-show')[0].offsetWidth
    let maxDefaultHeight = document.getElementsByClassName('file-content-show')[0].offsetHeight
    // 默认展示宽高
    let defaultWidth = 0
    let defaultHeight = 0
    // 当图片大于容器（长度大于容器的长，宽度大于容器的宽）
    if (this.originWidth > maxDefaultWidth || this.originHeight > maxDefaultHeight) {
      // 对比容器横向宽度
      if (this.originWidth / this.originHeight > maxDefaultWidth / maxDefaultHeight) {
        defaultWidth = maxDefaultWidth
        defaultHeight = Math.round(this.originHeight * (maxDefaultWidth / this.originWidth))
        posTop = (maxDefaultHeight - defaultHeight * ratio) / 2
        posLeft = 0
      } else {
        // 对比容器纵向宽度
        defaultWidth = Math.round(this.originWidth * (maxDefaultHeight / this.originHeight))
        defaultHeight = maxDefaultHeight
        posTop = 0
        posLeft = (maxDefaultWidth - defaultWidth * ratio) / 2
      }
    } else {
      defaultWidth = this.originWidth
      defaultHeight = this.originHeight
      posLeft = (maxDefaultWidth - defaultWidth * ratio) / 2
      posTop = (maxDefaultHeight - defaultHeight * ratio) / 2
    }
    // 若拖拽改变过位置,则在缩放操作时不改变当前位置
    if (this.isDraged) {
      this.setState({
        defaultWidth: defaultWidth * ratio,
        defaultHeight: defaultHeight * ratio,
      })
    } else {
      this.setState({
        posTop,
        posLeft,
        defaultWidth: defaultWidth * ratio,
        defaultHeight: defaultHeight * ratio,
      })
    }
  }
  /**
   * @name: scaleBig
   * @desc: 放大
   * @param {type} 放大的方式
   */
  scaleBig = (type = 'click') => {
    let { ratio } = this.state
    ratio += 0.15
    this.setState(
      {
        ratio,
      },
      () => {
        this.getImgSize()
      },
    )
  }

  /**
   * @name: scaleSmall
   * @desc: 缩小
   * @param {type} 缩小的方式
   */
  scaleSmall = (type = 'click') => {
    let { ratio } = this.state
    ratio -= 0.15
    if (ratio <= 0.1) {
      ratio = 0.1
    }
    this.setState(
      {
        ratio,
      },
      () => {
        this.getImgSize()
      },
    )
  }

  /**
   * @name: rotateRight
   * @desc: 向右旋转
   */
  rotateRight = () => {
    this.setState({
      angle: this.state.angle + 90,
    })
  }

  rotateLeft = () => {
    this.setState({
      angle: this.state.angle - 90,
    })
  }

  // 按下获取当前数据
  mouseDown = event => {
    let touch
    if (event.touches) {
      touch = event.touches[0]
    } else {
      touch = event
    }
    this.position = {
      x: touch.clientX,
      y: touch.clientY,
    }
    this.flags = true
    this.dx = this.imgEl.offsetLeft
    this.dy = this.imgEl.offsetTop
  }

  mouseMove = event => {
    if (this.flags) {
      event.preventDefault()
      let touch
      if (event.touches) {
        touch = event.touches[0]
      } else {
        touch = event
      }
      this.isDraged = true
      this.setState({
        posLeft: this.dx + touch.clientX - this.position.x,
        posTop: this.dy + touch.clientY - this.position.y,
      })
    }
  }

  mouseUp = () => {
    this.flags = false
  }

  mouseOut = () => {
    this.flags = false
  }

  // 滚轮缩放
  wheelScale = event => {
    if (event.deltaY < 0) {
      this.scaleBig('wheel')
    } else {
      this.scaleSmall('wheel')
    }
  }

  render() {
    let { posLeft, posTop, angle, imgSrc, defaultWidth, defaultHeight } = this.state
    return (
      <div className='preview-wrapper'>
        <div className='img-container'>
          <img
            className='image'
            width={defaultWidth}
            height={defaultHeight}
            style={{ transform: `rotate(${angle}deg)`, top: posTop + 'px', left: posLeft + 'px' }}
            onMouseDown={this.mouseDown}
            onMouseMove={this.mouseMove}
            onMouseUp={this.mouseUp}
            onMouseOut={this.mouseOut}
            draggable='false'
            onWheel={this.wheelScale}
            src={imgSrc}
            ref={img => {
              this.imgEl = img
            }}
            alt='预览图片'
          />
        </div>
      </div>
    )
  }
}

export default ImgPreview
